package main

import (
	"fmt"
	"runtime"
)

func main() {
	array := [8]int{1, 2, 3, 4, 5, 6, 7, 8}
	s := array[1:3]             // [2, 3]
	fmt.Println(cap(s), len(s)) // 7 2
	fmt.Printf("address of array[0] %p \n", &array[0])
	fmt.Printf("address of array[1] %p \n", &array[1]) // 0xc00001e218
	fmt.Printf("address of array[2] %p \n", &array[2]) // 0xc00001e220
	fmt.Printf("address of array[3] %p \n", &array[3])
	fmt.Printf("address of array[4] %p \n", &array[4])

	fmt.Printf("address of s[0] %p \n", &s[0]) // 0xc00001e218
	fmt.Printf("address of s[1] %p \n", &s[1]) // 0xc00001e220
	s[0] = 20                                  // array[1]也会变成20
	fmt.Printf("address of slice %p \n", s)    // 0xc0000b4008
	s = append(s, 40)
	fmt.Println(cap(s), len(s))             // cap=7, len=3
	fmt.Printf("address of slice %p \n", s) // 0xc0000b4008
	s = append(s, 50)
	fmt.Println(cap(s), len(s))             // cap=7, len=4
	fmt.Printf("address of slice %p \n", s) // 0xc0000b4008
	s = append(s, 60)
	fmt.Println(cap(s), len(s)) // cap=7, len=5
	s = append(s, 70)
	fmt.Println(cap(s), len(s)) // cap=7, len=6
	s = append(s, 80)
	fmt.Println(cap(s), len(s)) // cap=7, len=7
	s = append(s, 90)
	fmt.Println(cap(s), len(s))             // cap=14, len=8 触发扩容
	fmt.Printf("address of slice %p \n", s) // 0xc00001c140
	fmt.Println(s)                          // [20 3 40 50 60 70 80 90]
	fmt.Println(array)                      // [1 20 3 40 50 60 70 80]
	s[0] = 200
	fmt.Println(s)     // [200 3 40 50 60 70 80 90]
	fmt.Println(array) // [1 20 3 40 50 60 70 80]
	runtime.Gosched()
}

// 可以看到切片是共享数组里的部分数据的，是对里面元素的引用，
// 但是当它扩容后会变成一个新的切片(开辟新的内存空间),会把扩容前的那部分引用的数组的元素通过值拷贝的方式拷贝到新的内存空间里，
// 因此新切片无论怎么操作都不会影响老切片里的数据
